import bottleConf from '../../confs/bottle-conf'
import blockConf from '../../confs/block-conf'
import { customAnimation } from '../../libs/animation'
class Bottle {
  constructor () {
    this.status = 'stop'
    this.direction = 0
    this.axis = null
    this.scale = 1
  }

  init () {
    this.loader = new THREE.TextureLoader()
    this.obj = new THREE.Object3D()
    
    this.obj.name = 'bottle'

    this.obj.position.set(bottleConf.initPosition.x, blockConf.height / 2 + 30, bottleConf.initPosition.z)

    const {
      specularMaterial, 
      bottomMaterial,
      middleMaterial
    } = this.loadTexture()
    
    this.bottle = new THREE.Object3D()
    this.human = new THREE.Object3D()

    var headRadius = 2.1 * 0.72
    this.head = new THREE.Mesh(new THREE.OctahedronGeometry(headRadius * 1.4), specularMaterial)
    this.head.castShadow = true
    this.head.position.y = 7.56
    this.head.position.x = 0
    this.head.position.z = 0

    this.bottom = new THREE.Mesh(
      new THREE.CylinderGeometry(0.88 * headRadius, 1.27 * headRadius, 2.68 * headRadius, 20),
      bottomMaterial
    )
    this.bottom.castShadow = true

    var middleGeometry = new THREE.CylinderGeometry(headRadius, 0.88 * headRadius, 1.2 * headRadius, 20)
    this.middle = new THREE.Mesh(middleGeometry, middleMaterial)
    this.middle.castShadow = true
    this.middle.position.y = 1.3857 * headRadius
    this.middle.position.x = 0
    this.middle.position.z = 0
    
    var topGeometry = new THREE.SphereGeometry(headRadius, 20, 20)
    topGeometry.scale(1, 0.54, 1)
    var top = new THREE.Mesh(topGeometry, specularMaterial)
    top.castShadow = true
    top.position.y = 1.8143 * headRadius * 1.44
    top.position.x = 0
    top.position.z = 0

    this.body = new THREE.Object3D()
    this.body.add(this.bottom)
    this.body.add(this.middle)
    this.body.add(top)
    
    this.human.add(this.head)
    this.human.add(this.body)
    this.bottle.add(this.human)
    this.bottle.position.y = 2.2
    this.bottle.position.z = 0
    this.bottle.position.x = 0

    this.obj.add(this.bottle)
  }
  loadTexture () {
    const specularTexture = this.loader.load('/game/res/images/head.png')
    const specularMaterial = new THREE.MeshBasicMaterial({ map: specularTexture })

    const bottomTexture = this.loader.load('/game/res/images/bottom.png')
    const bottomMaterial = new THREE.MeshBasicMaterial({ map: bottomTexture })

    const middleTexture = new this.loader.load('/game/res/images/top.png')
    const middleMaterial = new THREE.MeshBasicMaterial({ map: middleTexture })

    return {
      specularMaterial, 
      bottomMaterial,
      middleMaterial
    }
  }
  _shrink () {
    const DELTA_SCALE = 0.005
    const HORIZON_DELTA_SCALE = 0.007
    const HEAD_DELTA = 0.03
    const MIN_SCALE = 0.55
    this.scale -= DELTA_SCALE
    this.scale = Math.max(MIN_SCALE, this.scale)
    if (this.scale <= MIN_SCALE) {
      return
    }
    this.body.scale.y = this.scale
    this.body.scale.x += HORIZON_DELTA_SCALE
    this.body.scale.z += HORIZON_DELTA_SCALE
    this.head.position.y -= HEAD_DELTA
    const bottleDeltaY = HEAD_DELTA / 2
    const deltaY = blockConf.height * DELTA_SCALE / 2
    this.obj.position.y -= (bottleDeltaY + deltaY * 2)
  }
  stop () {
    this.scale = 1
    this.status = 'stop'
  }
  shrink () {
    this.status = 'shrink'
  }
  update () {
    if (this.status == 'shrink') {
      this._shrink()
    }
    this.head.rotation.y += 0.06
  }
  showup () {
    customAnimation.to(
      0.5,
      this.obj.position,
      { x: bottleConf.initPosition.x,
        y: bottleConf.initPosition.y + blockConf.height / 2,
        z: bottleConf.initPosition.z,
      },
      'Linear'
    )
  }
  rotate () {    
    const scale = 1.4
    this.human.rotation.z = this.human.rotation.x = 0
    if (this.direction == 0) { // x
      console.log(111)
      customAnimation.to(0.14, this.human.rotation, { z: this.human.rotation.z - Math.PI }, 'Linear')
      customAnimation.to(0.18, this.human.rotation, { z: this.human.rotation.z - 2 * Math.PI }, 'Linear', 0.14)
      customAnimation.to(0.1, this.head.position, { y: this.head.position.y + 0.9 * scale, x: this.head.position.x + 0.45 * scale }, 'Linear')
      customAnimation.to(0.1, this.head.position, { y: this.head.position.y - 0.9 * scale, x: this.head.position.x - 0.45 * scale }, 'Linear', 0.1)
      customAnimation.to(0.15, this.head.position, { y: 7.56, x: 0 }, 'Linear', 0.25)
      customAnimation.to(0.1, this.body.scale, { y: Math.max(scale, 1), x: Math.max(Math.min(1 / scale, 1), 0.7), z: Math.max(Math.min(1 / scale, 1), 0.7) }, 'Linear')
      customAnimation.to(0.1, this.body.scale, { y: Math.min(0.9 / scale, 0.7), x: Math.max(scale, 1.2), z: Math.max(scale, 1.2) }, 'Linear', 0.1)
      customAnimation.to(0.3, this.body.scale, { y: 1, x: 1, z: 1 }, 'Linear', 0.2)
    } else if (this.direction == 1) { // z
      customAnimation.to(0.14, this.human.rotation, { x: this.human.rotation.x - Math.PI }, 'Linear')
      customAnimation.to(0.18, this.human.rotation, { x: this.human.rotation.x - 2 * Math.PI }, 'Linear', 0.14)
      customAnimation.to(0.1, this.head.position, { y: this.head.position.y + 0.9 * scale, z: this.head.position.z - 0.45 * scale }, 'Linear')
      customAnimation.to(0.1, this.head.position, { y: this.head.position.y - 0.9 * scale, x: this.head.position.x - 0.45 * scale }, 'Linear', 0.1)
      customAnimation.to(0.15, this.head.position, { y: 7.56, x: 0 }, 'Linear', 0.25)
      customAnimation.to(0.05, this.body.scale, { y: Math.max(scale, 1), x: Math.max(Math.min(1 / scale, 1), 0.7), z: Math.max(Math.min(1 / scale, 1), 0.7) }, 'Linear')
      customAnimation.to(0.05, this.body.scale, { y: Math.min(0.9 / scale, 0.7), x: Math.max(scale, 1.2), z: Math.max(scale, 1.2) }, 'Linear', 0.1)
      customAnimation.to(0.2, this.body.scale, { y: 1, x: 1, z: 1 }, 'Linear', 0.2)
    }
  }
}

export default new Bottle()

